#include "device.h"

int dev_id_min = 10000;
int dev_count = 0;

// 生成ID
int generate_id() 
{
    // 从内存中获取当前最小ID，生成新ID后更新内存
    int new_id = dev_id_min;
    dev_id_min++;  // 下次ID自增
    return new_id;
}


// 从文件加载设备数据
node_t *load_devices()
{
    node_t *head = create_dlist();
    FILE *fp = fopen(DEV_FILE, "r");
    if (!fp) {  // 文件不存在，初始化
        fp = fopen(DEV_FILE, "w+");
        fprintf(fp, "10001\n0\n"); 
        fclose(fp);
        return head;
    }
    
    // 读取第一行（最小ID）和第二行（设备数量）
    fscanf(fp, "%d\n%d\n", &dev_id_min, &dev_count);
    
    device_t temp = {0};
    // 用%31s限制字符串长度，避免溢出
    // 用%[^\n]但需调整分隔逻辑(空格)
    while (fscanf(fp, "%d %d %d %f %31s %31s %31s %f %31[^\n]\n",
                 &temp.dev_id, &temp.dev_order, &temp.dev_status,
                 &temp.cur_value, temp.dev_name, temp.dev_type,
                 temp.dev_ip, &temp.power_ele, temp.dev_desc) == 9) 
	{
        insert_tdlist(head, &temp, sizeof(device_t));
    }
    
    fclose(fp);
    return head;
}


// 将设备数据保存到文件
int save_devices(node_t *head)
{
	SYSERR(NULL,==,head,"head is NULL",-1); 
	FILE *fp = fopen(DEV_FILE, "w");
	SYSERR(NULL,==,fp,"fopen failed",-1);

	// 重新计算设备数量并更新序号
	int order = 1;
	node_t *temp = head->after;
	while(temp != head) 
	{
		((device_t *)temp->data)->dev_order = order++; 
		temp = temp->after;
	}

	// 更新总数量
	dev_count = order - 1;  

	fprintf(fp,"%d\n%d\n",dev_id_min,dev_count);

	temp = head->after;
	while(temp != head)
	{   
		device_t *devp = (device_t *)temp->data;
		fprintf(fp,"%d %d %d %f %s %s %s %f %s\n",
				devp->dev_id, devp->dev_order, devp->dev_status,
				devp->cur_value, devp->dev_name, devp->dev_type,
                devp->dev_ip, devp->power_ele, devp->dev_desc);
        temp = temp->after;
    }

    fclose(fp);
    destroy_dlist(&head);
    return 0;
}


// 添加设备函数
int add_dev(node_t * head, const device_t * newdev)
{
    SYSERR(NULL,==,head,"head is NULL",-1);
    SYSERR(NULL,==,newdev,"newdev is NULL",-1);
    
    // 计算新设备的序号：当前设备数量 + 1
    device_t temp_dev = *newdev;  
    temp_dev.dev_order = dev_count + 1;

    //尾部插入
    insert_tdlist(head, &temp_dev, sizeof(device_t));
    dev_count++;  // 添加后总数+1
    
    return 0;
}


// 显示设备
void show_dev(node_t *head, showfun_t showfun)
{
    SYSERR(NULL,==,head,"head is NULL",); 
    node_t *temp = head->after;
    printf("Order  ID    Name   Type      Ip            status   Value    Power      Desc\n");
    
	while (temp != head) 
    {
        showfun(temp->data);
        temp = temp->after;
    }
}


// 查找设备
node_t *find_dev(node_t *head, cmpfun_t cmpfun, const device_t *dev)
{
    SYSERR(NULL,==,head,"head is NULL",NULL);
    SYSERR(NULL,==,dev,"dev is NULL",NULL);
	node_t *result_list = create_dlist();
	node_t *temp = head->after;

	while( temp != head )
	{
        if (cmpfun(temp->data, dev) == 0)  
        {
            device_t *dev_data = (device_t *)temp->data;
            insert_tdlist(result_list, dev_data, sizeof(device_t));
        }
        temp = temp->after;  
	}
    
    // 如果结果链表为空，销毁并返回NULL
    if (result_list->after == result_list) 
    {
        destroy_dlist(&result_list);
        return NULL;
    }

    return result_list;
}


// 删除设备
int del_dev(node_t *head, cmpfun_t cmpfun, const device_t *dev)
{
    SYSERR(NULL,==,head,"head is NULL",-1);
    SYSERR(NULL,==,dev,"dev is NULL",-2);
    node_t *result;
    int delete_count = 0;  // 记录删除的设备数量
    
    // 循环删除所有匹配的设备
    while ((result = delete_vdlist(head, dev, cmpfun)) != NULL)
    {
        delete_count++;  // 每成功删除一个设备，计数器加1
    }
    
    // 根据删除数量返回相应状态
    if (delete_count == 0)
        return -1;  // 没有找到可删除的设备
    else
        return 0;   // 成功删除至少一个设备
}


//排序设备
int sort_dev(node_t *head, cmpfun_t cmpfun) 
{
    SYSERR(NULL, ==, head, "head is NULL", -1);

    // 排序链表
    selectSort_dlist(head, cmpfun);

    // 获取有效节点数
    int n = 0;
    node_t *count_temp = head->after;  // 从第一个数据节点开始计数
    while (count_temp != head && count_temp != NULL) { 
        n++;
        count_temp = count_temp->after;
    }
    if (n == 0) {
        printf("no device\n");
        return -1;
    }

    // 赋值序号
    node_t *temp = head->after;  
    for (int i = 1; i <= n; i++) {  
        // 避免空节点
        if (temp == NULL || temp->data == NULL) {
            break;  
        }
        device_t *dev_data = (device_t *)temp->data;
        dev_data->dev_order = i;  

        // 移动到下一个节点
        temp = temp->after;
        if (temp == head) { 
            break;
        }
    }

    return 0;
}


// 操控设备
node_t *control_dev(node_t *head,int to_status,int id)
{
     
  	if(to_status == 0) 
	{
        device_t temp = {.dev_status = to_status,.cur_value = 0};
		node_t *result = update_dev(head, id, 3, &temp);
		result = update_dev(head,id,4,&temp);
        if(result == NULL) 
              return NULL;
	}
    else if(to_status == 1) 
    {
        device_t temp = {.dev_status = to_status,.cur_value = 0};
        clear_input_buffer();
        printf("input dev value:\n");
        scanf("%f",&temp.cur_value);

		node_t *result = update_dev(head, id, 3, &temp);
		result = update_dev(head,id,4,&temp);
        if(result == NULL) 
              return NULL;
	}

    return head;  
}


// 更新设备
node_t *update_dev(node_t *head, int id, int updateMode, const device_t *updatedev)
{
    SYSERR(NULL, ==, head, "head is NULL", NULL);
    SYSERR(NULL, ==, updatedev, "updatedev is NULL", NULL);
    SYSERR(0, ==, id, "id cannot be 0", NULL); 

    device_t temp = {.dev_id = id};
	node_t *current = head->after;       // 用于遍历的当前节点
	node_t *last_updated = NULL; 	     // 记录最后一个被更新的节点

    // 遍历整个链表（避免依赖find_vdlist的内部逻辑）
    while (current != head)
    {
        // 检查当前节点是否匹配id（直接调用比较函数，不依赖find_vdlist）
        if (cmpDev_ID(current->data, &temp) == 0)
        {
            device_t *p = (device_t *)current->data;
            if (p == NULL)
            {
                current = current->after; // 跳过无效数据节点
                continue;
            }

            // 根据updateMode更新
            if (updateMode == 1)
            {
				if(strcmp(p->dev_name, updatedev->dev_name) == 0) return NULL;
                strncpy(p->dev_name, updatedev->dev_name, sizeof(p->dev_name) - 1);
                p->dev_name[sizeof(p->dev_name) - 1] = '\0';
                last_updated = current;
            }
            else if (updateMode == 2)
            {
				if(strcmp(p->dev_type, updatedev->dev_type) == 0) return NULL;
				strncpy(p->dev_type, updatedev->dev_type, sizeof(p->dev_type) - 1);
				p->dev_type[sizeof(p->dev_type) - 1] = '\0';
				last_updated = current;
			}
			else if (updateMode == 3)
			{
				if((p->dev_status - updatedev->dev_status) == 0) return NULL;
				p->dev_status = updatedev->dev_status;
				last_updated = current;
			}
			else if (updateMode == 4)
			{
				if((p->cur_value - updatedev->cur_value) == 0) return NULL;
				p->cur_value = updatedev->cur_value;
				last_updated = current;
			}	
			else
			{
				printf("UpdateMode error\n");
				break;
			}
		}
		current = current->after;
        
		if (current == head)
            break;
    }

    return last_updated;
}


// 清空设备
int clear_dev(node_t *head)
{
    SYSERR(NULL,==,head,"head is NULL",-1);
	node_t *temp = head->after,*before = head->after;
	
	while(temp != head)
	{
		temp = temp->after;
		free(before->data);
		free(before);
		before = temp;
	}

    free(before->data);
	free(before);
    temp->after = temp;
   	temp->before = temp;
	
	return 0;
}


// 显示函数(所有)
void showDev_All(const void *data) 
{
    const device_t *dev = (const device_t *)data;
    // 使用固定宽度指定字段宽度，负-表示左对齐，确保各列对齐
	printf("%-3d  %-6d  %-5s  %-8s  %-15s  %-5d  %-6.2f  %-5.2f\t%s\n",
            dev->dev_order,    // 序号
            dev->dev_id,       // ID
            dev->dev_name,     // 名称
            dev->dev_type,     // 类型
            dev->dev_ip,       // IP地址
            dev->dev_status,   // 状态
            dev->cur_value,    // 当前值(10字符宽，保留2位小数)
            dev->power_ele,    // 功率(10字符宽，保留2位小数)
            dev->dev_desc);    // 描述(默认左对齐)
}
    

// 比较函数(ID，设备名，类型)
int cmpDev_ID(const void *data1, const void *data2)
{
    const device_t *devp1 = (const device_t *)data1;
	const device_t *devp2 = (const device_t *)data2;
	return devp1->dev_id - devp2->dev_id;
}
int cmpDev_Name(const void *data1,const void *data2)
{
    const device_t *devp1 = (const device_t *)data1;
	const device_t *devp2 = (const device_t *)data2;
	return strcmp(devp1->dev_name,devp2->dev_name);
}
int cmpDev_Type(const void *data1,const void *data2)
{
    const device_t *devp1 = (const device_t *)data1;
	const device_t *devp2 = (const device_t *)data2;
	return strcmp(devp1->dev_type,devp2->dev_type);
}
int cmpDev_Status(const void *data1,const void *data2)
{
    const device_t *devp1 = (const device_t *)data1;
	const device_t *devp2 = (const device_t *)data2;
	return devp1->dev_status - devp2->dev_status;
}
